﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using UFIDA.U9.WSS.ProxyService.Utils;
using UFSoft.UBF.Util.Log;

namespace UFIDA.U9.WSS.ProxyService.Behavior.Endpoint
{
    public class Log4NetEndpointBehavior : IDispatchMessageInspector, IEndpointBehavior
    {
        private static readonly ILogger Logger = LoggerManager.GetLogger(typeof(Log4NetEndpointBehavior));

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            StringBuilder sb = new StringBuilder();
            string guid = Guid.NewGuid().ToString();
            sb.AppendFormat("请求标识:{0}，调用前日志", guid).AppendLine();
            try
            {
                Uri requestUri = request.Headers.To;
                sb.AppendFormat("请求地址:{0}", requestUri).AppendLine();
                OperationContext context = OperationContext.Current;
                MessageProperties prop = context.IncomingMessageProperties;
                RemoteEndpointMessageProperty endpoint =
                    prop[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
                if (endpoint != null)
                {
                    sb.AppendFormat("请求IP:{0}", endpoint.Address).AppendLine();
                }

                HttpRequestMessageProperty httpReq =
                    (HttpRequestMessageProperty) request.Properties[HttpRequestMessageProperty.Name];
                sb.AppendFormat("请求方式:{0}", httpReq.Method).AppendLine();
                sb.AppendLine("请求Headers:");
                foreach (string header in httpReq.Headers.AllKeys)
                {
                    if (string.IsNullOrEmpty(header)) continue;
                    if (header.ToLower() == "cookie") continue;
                    sb.AppendFormat("{0}:{1}", header, httpReq.Headers[header]).AppendLine();
                }

                MessageHeaders incomingMessageHeaders = OperationContext.Current.IncomingMessageHeaders;
                string currentActionName = incomingMessageHeaders.Action;
                if (string.IsNullOrEmpty(currentActionName))
                    currentActionName =
                        incomingMessageHeaders.To.Segments[incomingMessageHeaders.To.Segments.Length - 1];
                SynchronizedKeyedCollection<string, DispatchOperation> operations =
                    OperationContext.Current.EndpointDispatcher.DispatchRuntime.Operations;
                DispatchOperation operation = operations.FirstOrDefault(d => d.Name == currentActionName);
                if (operation != null)
                {
                    string actionName =
                        OperationContext.Current.IncomingMessageProperties["HttpOperationName"] as string;
                    Type hostType = OperationContext.Current.Host.Description.ServiceType;
                    sb.AppendFormat("请求类:{0}", hostType.FullName).AppendLine();
                    sb.AppendFormat("请求方法:{0}", actionName).AppendLine();
                }

                sb.AppendLine("请求内容:");
                sb.AppendLine(MessageHelper.GetContent(ref request));
                Logger.Error(sb.ToString());
            }
            catch (Exception ex)
            {
                Logger.Error("日志记录异常:{0}", ex);
            }

            return guid;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            try
            {
                string guid = correlationState as string;
                StringBuilder sb = new StringBuilder();
                if (!string.IsNullOrWhiteSpace(guid))
                    sb.AppendFormat("请求标识:{0}，调用后日志", guid).AppendLine();
                string replyString = MessageHelper.GetContent(ref reply);
                if (reply.Properties.ContainsKey(HttpResponseMessageProperty.Name))
                {
                    HttpResponseMessageProperty httpResp =
                        reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;
                    if (httpResp != null)
                        sb.AppendFormat("返回状态:{0} / {1}", (int) httpResp.StatusCode, httpResp.StatusCode).AppendLine();
                }

                sb.AppendLine("返回内容:");
                sb.AppendLine(replyString);
                Logger.Error(sb.ToString());
            }
            catch (Exception ex)
            {
                Logger.Error("日志记录异常:{0}", ex);
            }
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }
}